﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace msap.UserControls
{
    /// <summary>
    /// Pager.xaml 的交互逻辑
    /// </summary>
    public partial class Pager : UserControl
    {
        public Pager()
        {
            InitializeComponent();
        }

        private int m_CurrentPage;
        private int m_MaxPage;

        public IEnumerable<object> OriginalItemsSource
        {
            get { return (IEnumerable<object>)GetValue(OriginalItemsSourceProperty); }
            set { SetValue(OriginalItemsSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for OriginalItemsSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty OriginalItemsSourceProperty =
            DependencyProperty.Register("OriginalItemsSource", typeof(IEnumerable<object>), typeof(Pager), new PropertyMetadata(null,Init));


        public IEnumerable<object> PagedItemsSource
        {
            get { return (IEnumerable<object>)GetValue(PagedItemsSourceProperty); }
            private set { SetValue(PagedItemsSourceProperty, value); }
        }

        // Using a DependencyProperty as the backing store for PagedItemsSource.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PagedItemsSourceProperty =
            DependencyProperty.Register("PagedItemsSource", typeof(IEnumerable<object>), typeof(Pager), new PropertyMetadata(null));

        public int ItemCountPerPage
        {
            get { return (int)GetValue(ItemCountPerPageProperty); }
            set { SetValue(ItemCountPerPageProperty, value); }
        }

        // Using a DependencyProperty as the backing store for ItemCountPerPage.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ItemCountPerPageProperty =
            DependencyProperty.Register("ItemCountPerPage", typeof(int), typeof(Pager), new PropertyMetadata(20,Init));



        public int DisplayPageCount
        {
            get { return (int)GetValue(DisplayPageCountProperty); }
            set { SetValue(DisplayPageCountProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DisplayPageCount.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DisplayPageCountProperty =
            DependencyProperty.Register("DisplayPageCount", typeof(int), typeof(Pager), new PropertyMetadata(10,Init));



        private static void Init(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Pager pager = d as Pager;
            if(pager.DisplayPageCount<=1)
            {
                throw new ArgumentException("DisplayPageCount must be larger than 1", "DisplayPageCount");
            }
            if(pager.ItemCountPerPage<=1)
            {
                throw new ArgumentException("ItemCountPerPage must be larger than 1", "ItemCountPerPage");
            }

            if((pager.OriginalItemsSource?.Count()??0)==0)
            {
                pager.lstPages.ItemsSource = null;
                pager.PagedItemsSource = null;
                return;
            }
            pager.m_CurrentPage = 1;
            
            pager.PagedItemsSource = pager.OriginalItemsSource.Take(pager.ItemCountPerPage);
            pager.m_MaxPage = (int)Math.Ceiling((decimal)pager.OriginalItemsSource.Count() / (decimal)pager.ItemCountPerPage);

            if(pager.DisplayPageCount<=pager.m_MaxPage)
            {
                pager.lstPages.ItemsSource = Enumerable.Range(1, pager.DisplayPageCount);
            }
            else
            {
                pager.lstPages.ItemsSource = Enumerable.Range(1, pager.m_MaxPage);
            }
            pager.lstPages.SelectedIndex = 0;
        }

        private void GotoPageCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.m_CurrentPage = Convert.ToInt32(e.Parameter);
            this.PagedItemsSource = this.OriginalItemsSource.Skip((this.m_CurrentPage - 1) * this.ItemCountPerPage).Take(this.ItemCountPerPage);
            this.lstPages.SelectedIndex = this.m_CurrentPage % this.DisplayPageCount == 0 ? this.DisplayPageCount-1 : this.m_CurrentPage % this.DisplayPageCount - 1;
        }

        private void PreviousPageCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.m_CurrentPage--;
            if(this.m_CurrentPage % this.DisplayPageCount == 0)//页码显示需要跳转到上一页
            {
                this.lstPages.ItemsSource = Enumerable.Range(this.m_CurrentPage - this.DisplayPageCount+1, this.DisplayPageCount);
                this.lstPages.SelectedIndex = this.DisplayPageCount-1;
            }
            else
            {
                this.lstPages.SelectedIndex--;
            }
            this.PagedItemsSource = this.OriginalItemsSource.Skip((this.m_CurrentPage - 1)*this.ItemCountPerPage).Take(this.ItemCountPerPage);

        }

        private void PreviousPageCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this.m_CurrentPage > 1 && (this.OriginalItemsSource?.Count()??0)>0;
        }

        private void LastPageCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.m_CurrentPage = this.m_MaxPage;
            int lastDisplayPageCount = this.m_MaxPage % this.DisplayPageCount;//最后一页的页码数
            if (lastDisplayPageCount == 0)//刚好除尽的情况
            {
                this.lstPages.ItemsSource = Enumerable.Range(this.m_MaxPage - this.DisplayPageCount+1, this.DisplayPageCount);
                this.lstPages.SelectedIndex = this.DisplayPageCount - 1;
            }
            else
            {
                this.lstPages.ItemsSource = Enumerable.Range(this.m_MaxPage - lastDisplayPageCount + 1, lastDisplayPageCount);
                this.lstPages.SelectedIndex = lastDisplayPageCount - 1;
            }
            this.PagedItemsSource = this.OriginalItemsSource.Skip((this.m_CurrentPage - 1) * this.ItemCountPerPage).Take(this.ItemCountPerPage);
        }


        private void FirstPageCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.m_CurrentPage = 1;
            this.PagedItemsSource = this.OriginalItemsSource.Take(this.ItemCountPerPage);
            if (this.DisplayPageCount <= this.m_MaxPage)
            {
                this.lstPages.ItemsSource = Enumerable.Range(1, this.DisplayPageCount);
            }
            else
            {
                this.lstPages.ItemsSource = Enumerable.Range(1, this.m_MaxPage);
            }
            this.lstPages.SelectedIndex = 0;
        }

        private void NextPageCommand_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            this.m_CurrentPage++;
            if (this.m_CurrentPage % this.DisplayPageCount == 1)//页码显示需要跳转到下一页
            {
                if (this.m_MaxPage - this.m_CurrentPage <= this.DisplayPageCount - 1)//最后一页的情况
                {
                    this.lstPages.ItemsSource = Enumerable.Range(this.m_CurrentPage, this.m_MaxPage - this.m_CurrentPage + 1);
                }
                else
                {
                    this.lstPages.ItemsSource = Enumerable.Range(this.m_CurrentPage, this.DisplayPageCount);
                }
                this.lstPages.SelectedIndex = 0;
            }
            else
            {
                this.lstPages.SelectedIndex++;
            }
            this.PagedItemsSource = this.OriginalItemsSource.Skip((this.m_CurrentPage - 1) * this.ItemCountPerPage).Take(this.ItemCountPerPage);
        }

        private void NextPageCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = this.m_CurrentPage < this.m_MaxPage && (this.OriginalItemsSource?.Count()??0)>0;
        }

        private void GotoPageCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = (this.OriginalItemsSource?.Count() ?? 0) > 0;
        }

        private void LastPageCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = (this.OriginalItemsSource?.Count() ?? 0) > 0;
        }

        private void FirstPageCommand_CanExecute(object sender, CanExecuteRoutedEventArgs e)
        {
            e.CanExecute = (this.OriginalItemsSource?.Count() ?? 0) > 0;
        }
    }
}
